/*
* // +-------------------------------------------------------------------------------------------------
* // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
* // +-------------------------------------------------------------------------------------------------
* // |                             独在异乡为异客         每逢佳节倍思亲
* // +-------------------------------------------------------------------------------------------------
* // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
* // +-------------------------------------------------------------------------------------------------
*/

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.admin.controller.system.rule


import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.plugins.Page
import org.apache.shiro.authz.annotation.RequiresPermissions
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.mvc.support.RedirectAttributes
import wang.encoding.mroot.admin.common.controller.BaseAdminController
import wang.encoding.mroot.admin.common.util.ShiroSessionUtil
import wang.encoding.mroot.common.annotation.FormToken
import wang.encoding.mroot.common.annotation.RequestLogAnnotation
import wang.encoding.mroot.common.business.ResultData
import wang.encoding.mroot.common.constant.RequestLogConstant
import wang.encoding.mroot.common.exception.ControllerException
import wang.encoding.mroot.model.entity.system.Rule
import wang.encoding.mroot.model.enums.RuleTypeEnum
import wang.encoding.mroot.model.enums.StatusEnum
import wang.encoding.mroot.service.event.RemoveRuleCacheEvent
import wang.encoding.mroot.service.system.RuleService
import java.math.BigInteger
import javax.servlet.http.HttpServletRequest


/**
 * 后台 权限 控制器
 *
 *@author ErYang
 */
@RestController
@RequestMapping(value = ["/rule"])
class RuleController : BaseAdminController() {

    @Autowired
    private lateinit var ruleService: RuleService


    companion object {

        /**
         * logger
         */
        private val logger: Logger = LoggerFactory.getLogger(RuleController::class.java)

        /**
         * 模块
         */
        private const val MODULE_NAME: String = "/rule"

        /**
         * 视图目录
         */
        private const val VIEW_PATH: String = "/system/rule"

        /**
         * 对象名称
         */
        private const val VIEW_MODEL_NAME: String = "rule"
        /**
         * 父级对象名称
         */
        private const val PARENT_VIEW_MODEL_NAME: String = "parentRule"
        /**
         * 首页
         */
        private const val INDEX: String = "/index"
        private const val INDEX_URL: String = MODULE_NAME + INDEX
        private const val INDEX_VIEW: String = VIEW_PATH + INDEX
        /**
         * 新增
         */
        private const val ADD: String = "/add"
        private const val ADD_URL: String = MODULE_NAME + ADD
        private const val ADD_VIEW: String = VIEW_PATH + ADD
        /**
         * 新增子级权限
         */
        private const val ADD_CHILDREN: String = "/addChildren"
        private const val ADD_CHILDREN_URL: String = MODULE_NAME + ADD_CHILDREN
        private const val ADD_CHILDREN_VIEW: String = VIEW_PATH + ADD_CHILDREN
        /**
         * 保存
         */
        private const val SAVE: String = "/save"
        private const val SAVE_URL: String = MODULE_NAME + SAVE
        /**
         * 修改
         */
        private const val EDIT: String = "/edit"
        private const val EDIT_URL: String = MODULE_NAME + EDIT
        private const val EDIT_VIEW: String = VIEW_PATH + EDIT
        /**
         * 更新
         */
        private const val UPDATE: String = "/update"
        private const val UPDATE_URL: String = MODULE_NAME + UPDATE
        /**
         * 查看
         */
        private const val VIEW: String = "/view"
        private const val VIEW_URL: String = MODULE_NAME + VIEW
        private const val VIEW_VIEW: String = VIEW_PATH + VIEW
        /**
         * 删除
         */
        private const val DELETE: String = "/delete"
        private const val DELETE_URL: String = MODULE_NAME + DELETE
        private const val DELETE_BATCH: String = "/deleteBatch"
        private const val DELETE_BATCH_URL: String = MODULE_NAME + DELETE_BATCH


        private const val ROLE_MODULE_NAME: String = "/role"
        private const val ROLE_INDEX: String = "/index"

        /**
         * 回收站
         */
        private const val RECYCLE_BIN_INDEX: String = "/recycleBin"
        private const val RECYCLE_BIN_INDEX_URL: String = MODULE_NAME + RECYCLE_BIN_INDEX
        private const val RECYCLE_BIN_INDEX_VIEW: String = VIEW_PATH + RECYCLE_BIN_INDEX
        /**
         * 恢复
         */
        private const val RECOVER: String = "/recover"
        private const val RECOVER_URL: String = MODULE_NAME + RECOVER

        private const val RECOVER_BATCH: String = "/recoverBatch"
        private const val RECOVER_BATCH_URL: String = MODULE_NAME + RECOVER_BATCH

    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 列表页面
     *
     * @param request HttpServletRequest
     * @return ModelAndView
     */
    @RequiresPermissions(value = [INDEX_URL])
    @RequestMapping(INDEX)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_INDEX)
    @Throws(ControllerException::class)
    fun index(request: HttpServletRequest): ModelAndView {
        val modelAndView = ModelAndView(super.initView(INDEX_VIEW))
        super.initViewTitleAndModelUrl(INDEX_URL, MODULE_NAME, request)

        val rule = Rule()
        val title: String? = request.getParameter("title")
        if (null != title && title.isNotBlank()) {
            rule.title = title
            modelAndView.addObject("title", title)
        }
        rule.status = StatusEnum.NORMAL.key
        val page: Page<Rule> = ruleService.list2page(super.initPage(request), rule, Rule.ID, false)!!
        modelAndView.addObject(VIEW_PAGE_NAME, page)

        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 添加页面
     *
     * @param request HttpServletRequest
     * @return ModelAndView
     */
    @RequiresPermissions(value = [ADD_URL])
    @RequestMapping(ADD)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_ADD)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun add(request: HttpServletRequest): ModelAndView {
        val modelAndView = ModelAndView(super.initView(ADD_VIEW))
        super.initViewTitleAndModelUrl(ADD_URL, MODULE_NAME, request)
        // 设置上个请求地址
        super.initRefererUrl(request)

        // 最大排序值
        val maxSort: Int = ruleService.getMax2Sort() + 1
        modelAndView.addObject("maxSort", maxSort)

        this.getRules2Tree(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 处理保存
     *
     * @param request HttpServletRequest
     * @param rule Rule
     * @return ModelAndView
     */
    @RequiresPermissions(value = [SAVE_URL])
    @RequestMapping(SAVE)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_SAVE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun save(request: HttpServletRequest, rule: Rule): Any {
        if (httpRequestUtil.isAjaxRequest(request)) {
            val failResult: ResultData = ResultData.fail()

            // 创建 Rule 对象
            val saveRule: Rule = this.initAddData(request, rule)

            // Hibernate Validation  验证数据
            val validationResult: String? = ruleService.validationRule(saveRule)
            if (null != validationResult && validationResult.isNotBlank()) {
                return super.initErrorHibernateValidationJSONObject(failResult, validationResult)
            }

            // 验证数据唯一性
            val flag: Boolean = this.validationAddData(saveRule, failResult)
            if (!flag) {
                return super.initErrorValidationJSONObject(failResult)
            }

            // 新增权限 id
            val id: BigInteger? = ruleService.saveBackId(saveRule)
            if (null != id && BigInteger.ZERO < id) {
                // 设置 session 中登录用户信息 的权限
                controllerAsyncTask.initUserRoleHasRules(super.getCurrentAdmin()!!, ShiroSessionUtil.getSession())
            }
            return super.initSaveJSONObject(id)
        } else {
            return super.initErrorRedirectUrl()
        }

    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 添加子级权限页面
     *
     * @param id String
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [ADD_CHILDREN_URL])
    @RequestMapping("$ADD_CHILDREN/{id}")
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_ADD_CHILDREN)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun addChildren(@PathVariable(ID_NAME) id: String, request: HttpServletRequest,
                    redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(ADD_CHILDREN_VIEW))

        super.initViewTitleAndModelUrl(ADD_CHILDREN_URL, MODULE_NAME, request)
        // 设置上个请求地址
        super.initRefererUrl(request)

        val idValue: BigInteger? = super.getId(id)
        if (null == idValue || BigInteger.ZERO > idValue) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 数据真实性
        val parentRule: Rule? = ruleService.getById(idValue)
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        if (StatusEnum.DELETE.key == parentRule!!.status) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 判断是否是按钮级的权限
        if (RuleTypeEnum.BUTTON.key == parentRule.type) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        modelAndView.addObject(PARENT_VIEW_MODEL_NAME, parentRule)

        // 最大排序值
        val maxSort: Int = ruleService.getMax2Sort() + 1
        modelAndView.addObject("maxSort", maxSort)
        this.getRules2Tree(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 编辑页面
     *
     * @param id String
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [EDIT_URL])
    @RequestMapping("$EDIT/{id}")
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_EDIT)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun edit(@PathVariable(ID_NAME) id: String, request: HttpServletRequest,
             redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(EDIT_VIEW))


        super.initViewTitleAndModelUrl(EDIT_URL, MODULE_NAME, request)
        val idValue: BigInteger? = super.getId(id)
        if (null == idValue || BigInteger.ZERO > idValue) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 数据真实性
        val rule: Rule? = ruleService.getById(idValue)
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        if (StatusEnum.DELETE.key == rule!!.status) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        modelAndView.addObject(VIEW_MODEL_NAME, rule)
        // 设置上个请求地址
        super.initRefererUrl(request)

        this.getRules2Tree(request)

        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 处理更新
     *
     * @param request HttpServletRequest
     * @param rule Rule
     * @return ModelAndView
     */
    @RequiresPermissions(value = [UPDATE_URL])
    @RequestMapping(UPDATE)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_UPDATE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun update(request: HttpServletRequest, rule: Rule): Any {
        if (httpRequestUtil.isAjaxRequest(request)) {
            val failResult: ResultData = ResultData.fail()
            // 验证数据
            val idValue: BigInteger? = super.getId(request)
            if (null == idValue || BigInteger.ZERO > idValue) {
                return super.initErrorCheckJSONObject(failResult)
            }
            // 数据真实性
            val ruleBefore: Rule = ruleService.getById(idValue)
                    ?: return super.initErrorCheckJSONObject(failResult)
            if (StatusEnum.DELETE.key == ruleBefore.status) {
                return super.initErrorCheckJSONObject(failResult)
            }

            // 创建 Rule 对象
            var editRule: Rule = Rule.copy2New(rule)
            editRule.id = ruleBefore.id
            val statusStr: String? = super.getStatusStr(request)
            when {
                statusStr.equals(configProperties.bootstrapSwitchEnabled) -> editRule.status = StatusEnum.NORMAL.key
                null == statusStr -> editRule.status = StatusEnum.DISABLE.key
                else -> editRule.status = StatusEnum.DISABLE.key
            }
            editRule = this.initEditData(editRule)

            // Hibernate Validation 验证数据
            val validationResult: String? = ruleService.validationRule(editRule)
            if (null != validationResult && validationResult.isNotBlank()) {
                return super.initErrorHibernateValidationJSONObject(failResult, validationResult)
            }

            // 验证数据唯一性
            val flag: Boolean = this.validationEditData(rule, ruleBefore, failResult)
            if (!flag) {
                return super.initErrorValidationJSONObject(failResult)
            }

            // 修改权限 id
            val id: BigInteger? = ruleService.updateBackId(editRule)
            if (null != id && BigInteger.ZERO < id) {
                // 设置 session 中登录用户信息 的权限
                controllerAsyncTask.initUserRoleHasRules(super.getCurrentAdmin()!!,
                        ShiroSessionUtil.getSession())
                // 异步清理缓存
                this.removeCacheEvent(id)
            }
            return super.initUpdateJSONObject(id)
        } else {
            return super.initErrorRedirectUrl()
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 查看页面
     *
     * @param id String
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [VIEW_URL])
    @RequestMapping("$VIEW/{id}")
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_VIEW)
    @Throws(ControllerException::class)
    fun view(@PathVariable(ID_NAME) id: String, request: HttpServletRequest,
             redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(VIEW_VIEW))
        super.initViewTitleAndModelUrl(VIEW_URL, MODULE_NAME, request)

        val idValue: BigInteger? = super.getId(id)
        // 验证数据
        if (null == idValue || BigInteger.ZERO > idValue) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 数据真实性
        val rule: Rule? = ruleService.getById(idValue)
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
        modelAndView.addObject(VIEW_MODEL_NAME, rule)
        // 设置上个请求地址
        super.initRefererUrl(request)

        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 删除
     * @param request HttpServletRequest
     * @param id String
     * @return JSONObject
     */
    @RequiresPermissions(value = [DELETE_URL])
    @RequestMapping("$DELETE/{id}")
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_DELETE)
    @Throws(ControllerException::class)
    fun delete(@PathVariable(ID_NAME) id: String, request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idValue: BigInteger? = super.getId(id)
            // 验证数据
            if (null == idValue || BigInteger.ZERO > idValue) {
                super.initErrorCheckJSONObject()
            }
            val rule: Rule? = ruleService.getById(idValue!!)
            if (null == rule) {
                super.initErrorCheckJSONObject()
            }
            // 有没有子级权限
            val ruleList: List<Rule>? = ruleService.listByPid(rule!!.id!!)
            if (null != ruleList && ruleList.isNotEmpty()) {
                val failResult: ResultData = ResultData.fail()
                return super.initErrorJSONObject(failResult, "message.system.rule.delete.error")
            }
            // 删除 Rule id
            val backId: BigInteger? = ruleService.removeBackId(rule.id!!)
            if (null != backId && BigInteger.ZERO < backId) {
                // 设置 session 中登录用户信息 的权限
                controllerAsyncTask.initUserRoleHasRules(super.getCurrentAdmin()!!,
                        ShiroSessionUtil.getSession())
                // 异步清理缓存
                this.removeCacheEvent(backId)
            }
            return super.initDeleteJSONObject(backId)
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 批量删除
     * @param request HttpServletRequest
     * @return JSONObject
     */
    @RequiresPermissions(value = [DELETE_BATCH_URL])
    @RequestMapping(DELETE_BATCH)
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_DELETE_BATCH)
    @Throws(ControllerException::class)
    fun deleteBatch(request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idArray: ArrayList<BigInteger>? = super.getIdArray(request)
            // 验证数据
            if (null == idArray || idArray.isEmpty()) {
                super.initErrorCheckJSONObject()
            }
            // 有没有子级权限
            val ruleList: List<Rule>? = ruleService.listByPidArray(idArray)
            if (null != ruleList && ruleList.isNotEmpty()) {
                val failResult: ResultData = ResultData.fail()
                return super.initErrorJSONObject(failResult, "message.system.rule.delete.error")
            }

            var flag = false
            if (null != idArray) {
                flag = ruleService.removeBatch2UpdateStatus(idArray)!!
            }

            return if (flag) {
                // 设置 session 中登录用户信息 的权限
                controllerAsyncTask.initUserRoleHasRules(super.getCurrentAdmin()!!,
                        ShiroSessionUtil.getSession())
                // 异步清理缓存
                this.removeBatchCacheEvent(idArray!!)
                super.initDeleteJSONObject(BigInteger.ONE)
            } else {
                super.initDeleteJSONObject(BigInteger.ZERO)
            }
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 回收站页面
     *
     * @param request HttpServletRequest
     * @return ModelAndView
     */
    @RequiresPermissions(value = [RECYCLE_BIN_INDEX_URL])
    @RequestMapping(RECYCLE_BIN_INDEX)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_RECYCLE_BIN_INDEX)
    @Throws(ControllerException::class)
    fun recycleBin(request: HttpServletRequest): ModelAndView {
        val modelAndView = ModelAndView(super.initView(RECYCLE_BIN_INDEX_VIEW))
        super.initViewTitleAndModelUrl(RECYCLE_BIN_INDEX_URL, MODULE_NAME, request)

        val rule = Rule()
        val title: String? = request.getParameter("title")
        if (null != title && title.isNotBlank()) {
            rule.title = title
            modelAndView.addObject("title", title)
        }
        rule.status = StatusEnum.DELETE.key
        val page: Page<Rule> = ruleService.list2page(super.initPage(request), rule, Rule.ID, false)!!
        modelAndView.addObject(VIEW_PAGE_NAME, page)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 恢复
     * @param request HttpServletRequest
     * @param id String
     * @return JSONObject
     */
    @RequiresPermissions(value = [RECOVER_URL])
    @RequestMapping("$RECOVER/{id}")
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_RECOVER)
    @Throws(ControllerException::class)
    fun recover(@PathVariable(ID_NAME) id: String, request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idValue: BigInteger? = super.getId(id)
            // 验证数据
            if (null == idValue || BigInteger.ZERO > idValue) {
                super.initErrorCheckJSONObject()
            }
            val rule: Rule? = ruleService.getById(idValue!!)
            if (null == rule) {
                super.initErrorCheckJSONObject()
            }
            // 恢复权限 id
            val backId: BigInteger? = ruleService.recoverBackId(rule!!.id!!)
            if (null != backId && BigInteger.ZERO < backId) {
                // 设置 session 中登录用户信息 的权限
                controllerAsyncTask.initUserRoleHasRules(super.getCurrentAdmin()!!,
                        ShiroSessionUtil.getSession())
                // 异步清理缓存
                this.removeCacheEvent(backId)
            }
            return super.initRecoverJSONObject(backId)
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 批量恢复
     * @param request HttpServletRequest
     * @return JSONObject
     */
    @RequiresPermissions(value = [RECOVER_BATCH_URL])
    @RequestMapping(RECOVER_BATCH)
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_RULE_RECOVER_BATCH)
    @Throws(ControllerException::class)
    fun recoverBatch(request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idArray: ArrayList<BigInteger>? = super.getIdArray(request)
            // 验证数据
            if (null == idArray || idArray.isEmpty()) {
                super.initErrorCheckJSONObject()
            }
            var flag = false
            if (null != idArray) {
                flag = ruleService.recoverBatch2UpdateStatus(idArray)!!
            }
            return if (flag) {
                // 设置 session 中登录用户信息 的权限
                controllerAsyncTask.initUserRoleHasRules(super.getCurrentAdmin()!!,
                        ShiroSessionUtil.getSession())
                // 异步清理缓存
                this.removeBatchCacheEvent(idArray!!)
                super.initRecoverJSONObject(BigInteger.ONE)
            } else {
                super.initRecoverJSONObject(BigInteger.ZERO)
            }
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证数据 合法性
     *
     * @param request HttpServletRequest
     * @param rule         Rule
     * @return Rule
     */
    private fun initAddData(request: HttpServletRequest, rule: Rule): Rule {
        val addRule: Rule = Rule.copy2New(rule)
        if (null == addRule.pid) {
            addRule.pid = BigInteger.ONE
        }
        // ip
        addRule.gmtCreateIp = super.getIp(request)
        // 创建 Rule 对象
        return ruleService.initSaveRule(addRule)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证数据 合法性
     *
     * @param rule         Rule
     * @return Rule
     */
    private fun initEditData(rule: Rule): Rule {
        val editRule: Rule = rule
        if (null == editRule.pid) {
            editRule.pid = BigInteger.ONE
        }
        // 创建 Rule 对象
        return ruleService.initEditRule(editRule)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证数据 数据的唯一性
     *
     * @param rule         Rule
     * @param failResult ResultData
     * @return Boolean true(通过)/false(未通过)
     */
    private fun validationAddData(rule: Rule, failResult: ResultData): Boolean {
        val message: String
        // 是否存在
        val titleExist: Rule? = ruleService.getByTitle(rule.title!!.trim().toLowerCase())
        if (null != titleExist) {
            message = localeMessageSourceConfiguration.getMessage(BaseAdminController.MESSAGE_TITLE_EXIST_NAME)
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        val urlExist: Rule? = ruleService.getByUrl(rule.url!!.trim().toLowerCase())
        if (null != urlExist) {
            message = localeMessageSourceConfiguration.getMessage("message.system.rule.url.exist")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        // 判断子级菜单是否大于父级菜单
        if (null != rule.pid) {
            // 得到上级权限
            val pidRule: Rule? = ruleService.getById(rule.pid!!)
            // 子级菜单类型超过父级菜单类型
            if (null != pidRule) {
                if (rule.type!! < pidRule.type!!) {
                    message = localeMessageSourceConfiguration.getMessage("message.system.rule.type.exceed.pidRule.type.error")
                    failResult.setFail()[configProperties.messageName] = message
                    return false

                }
            } else {
                message = localeMessageSourceConfiguration.getMessage("message.system.rule.pidRule.error")
                failResult.setFail()[configProperties.messageName] = message
                return false
            }
        }
        return true
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证修改数据 数据的唯一性 合法性
     *
     * @param newRule               权限
     * @param rule            权限
     * @param failResult ResultData
     * @return 验证结果
     */
    private fun validationEditData(newRule: Rule, rule: Rule,
                                   failResult: ResultData): Boolean {
        val message: String
        // 名称是否存在
        val titleExist: Boolean = ruleService.propertyUnique(Rule.TITLE, newRule.title!!.trim().toLowerCase(),
                rule.title!!.toLowerCase())
        if (!titleExist) {
            message = localeMessageSourceConfiguration.getMessage(BaseAdminController.MESSAGE_TITLE_EXIST_NAME)
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        val urlExist: Boolean = ruleService.propertyUnique(Rule.URL, newRule.url!!.trim().toLowerCase(),
                rule.url!!.toLowerCase())
        if (!urlExist) {
            message = localeMessageSourceConfiguration.getMessage("message.system.rule.url.exist")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        // 判断子级菜单是否大于父级菜单
        if (null != newRule.pid) {
            // 得到上级权限
            val pidRule: Rule? = ruleService.getById(newRule.pid!!)
            // 子级菜单类型超过父级菜单类型
            if (null != pidRule) {
                if (newRule.type!! < pidRule.type!!) {
                    message = localeMessageSourceConfiguration.getMessage("message.system.rule.type.exceed.pidRule.type.error")
                    failResult.setFail()[configProperties.messageName] = message
                    return false
                }
            } else {
                message = localeMessageSourceConfiguration.getMessage("message.system.rule.pidRule.error")
                failResult.setFail()[configProperties.messageName] = message
                return false
            }
        }
        return true

    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 得到权限菜单(小于4级)
     */
    private fun getRules2Tree(request: HttpServletRequest) {
        // 权限 tree 数据
        val list: List<Rule>? = ruleService.listPidGt0AndTypeLt4()
        if (null != list) {
            request.setAttribute("treeRules", list)
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 根据 ID 清理缓存
     *
     * @param id         BigInteger
     *
     */
    private fun removeCacheEvent(id: BigInteger) {
        // 异步清理缓存
        val removeConfigCacheEvent = RemoveRuleCacheEvent(this, id)
        super.applicationContext.publishEvent(removeConfigCacheEvent)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 根据 ID 集合批量清理缓存
     *
     * @param idArray         ArrayList<BigInteger>
     *
     */
    private fun removeBatchCacheEvent(idArray: ArrayList<BigInteger>) {
        // 异步清理缓存
        val removeConfigCacheEvent = RemoveRuleCacheEvent(this, idArray)
        super.applicationContext.publishEvent(removeConfigCacheEvent)
    }

    // -------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End RuleController class

/* End of file RuleController.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/admin/controller/system/rule/RuleController.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------
